#ifndef PROCESSMANAGEMENTDIALOG_H
#define PROCESSMANAGEMENTDIALOG_H

#include "global.h"
#include <QDialog>

namespace Ui {
class ProcessManagementDialog;
}


class QMenu;
class QTreeWidgetItem;

class ProcessManagementDialog : public QDialog
{
    Q_OBJECT

public:
    explicit ProcessManagementDialog(QSqlDatabase &database, QWidget *parent = 0);
    ~ProcessManagementDialog();

    struct BasicInfoMaps;
    struct Info;
    bool isEditMode() const;

public slots:
    void setEditMode(bool = true);
    void setCurrentDisplayInfo(const Info &);
    void froze(bool = true);
    void clearInfoFrame();
    void saveInfoFrame();
private:
    Ui::ProcessManagementDialog *ui;
    QSqlQuery query;
    QMenu *insertNewProcessMenu = nullptr;
    QMenu *addNewProcessMenu = nullptr;
    BasicInfoMaps *basicInfoMaps = nullptr;
    QMap<QTreeWidgetItem *, Info> infos;
    bool __editMode = false;
    bool __systemMode = false;

    void buildTree();
    bool insertNewProcessInDatabase();
    bool isTopLevelTreeWidgetItem(QTreeWidgetItem *);

private slots:
    void onCurrentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*);
    void onOfferStatusValueChanged(int);
    void insertProcess();
    void onTreeWidgetContextMenuRequired(QPoint);
};

struct ProcessManagementDialog::BasicInfoMaps
{
    using NameMapId = QMap<QString, int>;
    using IdMapName = QMap<int, QString>;
    NameMapId companyNameMapId;
    NameMapId processNameMapId;
    NameMapId statusNameMapId;
    IdMapName idMapCompanyName;
    IdMapName idMapProcessName;
    IdMapName idMapStatusName;

    BasicInfoMaps() = delete;
    BasicInfoMaps(const QSqlQuery &);
private:
    QSqlQuery query;
    NameMapId buildNameMapId(const QString &, const QString &);
    IdMapName buildIdMapName(const NameMapId &);
};

struct ProcessManagementDialog::Info
{
    int companyId;
    QString planBeginTime;
    QString planEndTime;
    QString informTime;
    int sequence;
    int processId;
    int statusId;
    QString remark;
    Info() = default;
    Info(QSqlQuery &, ProcessManagementDialog::BasicInfoMaps *);
    QDateTime planBeginTimeToQDateTime() const;
    QDateTime planEndTimeToQDateTime() const;
    QDateTime informTimeToQDateTime() const;
    QString companyIdToName() const;
    QString processIdToName() const;
    QString statusIdToName() const;
    void qDateTimeToPlanBeginTime(const QDateTime &);
    void qDateTimeToPlanEndTime(const QDateTime &);
    void qDateTimeToInformTime(const QDateTime &);
    bool save(const QSqlQuery &);
private:
    ProcessManagementDialog::BasicInfoMaps *basicInfoMaps;
};

inline QDateTime ProcessManagementDialog::Info::planBeginTimeToQDateTime() const
{
    return QDateTime::fromString(planBeginTime, Global::STANDARD_DATE_TIME_FORMAT);
}
inline QDateTime ProcessManagementDialog::Info::planEndTimeToQDateTime() const
{
    return QDateTime::fromString(planEndTime, Global::STANDARD_DATE_TIME_FORMAT);
}
inline QDateTime ProcessManagementDialog::Info::informTimeToQDateTime() const
{
    return QDateTime::fromString(informTime, Global::STANDARD_DATE_TIME_FORMAT);
}
inline QString ProcessManagementDialog::Info::companyIdToName() const
{
    return this->basicInfoMaps->idMapCompanyName[this->companyId];
}
inline QString ProcessManagementDialog::Info::processIdToName() const
{
    return this->basicInfoMaps->idMapProcessName[this->processId];
}
inline QString ProcessManagementDialog::Info::statusIdToName() const
{
    return this->basicInfoMaps->idMapStatusName[this->statusId];
}
inline void ProcessManagementDialog::Info::qDateTimeToPlanBeginTime(const QDateTime &dateTime)
{
    this->planBeginTime = dateTime.toString(Global::STANDARD_DATE_TIME_FORMAT);
}
inline void ProcessManagementDialog::Info::qDateTimeToPlanEndTime(const QDateTime &dateTime)
{
    this->planEndTime = dateTime.toString(Global::STANDARD_DATE_TIME_FORMAT);
}
inline void ProcessManagementDialog::Info::qDateTimeToInformTime(const QDateTime &dateTime)
{
    this->informTime = dateTime.toString(Global::STANDARD_DATE_TIME_FORMAT);
}
#endif // PROCESSMANAGEMENTDIALOG_H
